﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;

using Bricks.Component.Utils;
using Bricks.Business.Models;
using Bricks.Business.Models.FlowProcess;
using Bricks.Site.Models;
using Bricks.Business.Data.Repositories.WorkerManagement;
using System.Xml;
using Bricks.Business.Service;
using Bricks.Business.Models.WorkerManagement;
using Bricks.Component.Data;
using Bricks.Site.Models.DBViewModel.Contract;
using Bricks.Business.Models.Document;
using Bricks.Business.Data.Repositories.Document;


namespace ChiDao.Business.Service.Impl
{
    [Export(typeof(ISectionSalaryService))]
    internal class SectionSalaryService : ISectionSalaryService
    {
        #region 属性
        [Import]
        protected ISectionSalaryRepository SectionSalaryRepository { get; set; }
        [Import]
        protected ISectionSalaryDetailsRepository SectionSalaryDetailsRepository { get; set; }
        [Import]
        protected IDocumentInfoRepository DocumentInfoRepository { get; set; }

        public IQueryable<SectionSalary> SectionSalarys
        {
            get { return SectionSalaryRepository.Entities; }
        }
        #endregion

        #region 主界面加载
        public List<SectionSalaryView> GetSectionSalaryList(Guid projectID, string contractType, string year)
        {
            List<SectionSalaryView> lstSectionSalaryView = new List<SectionSalaryView>();
            IQueryable<SectionSalary> lstSectionSalary = SectionSalaryRepository.Entities.Where(s => s.ProjectID == projectID && s.ContractType == contractType && s.Year == year && s.HandleState == "2");
            foreach (SectionSalary sectionSalary in lstSectionSalary)
            {
                SectionSalaryView sectionSalaryView = lstSectionSalaryView.SingleOrDefault(s => s.ContractID == sectionSalary.ContractID);
                if (sectionSalaryView == null)
                {
                    sectionSalaryView = new SectionSalaryView();
                    sectionSalaryView.ProjectID = projectID;
                    sectionSalaryView.ContractType = contractType;
                    sectionSalaryView.ContractID = sectionSalary.ContractID;
                    string sql = "select * from V_ContractInfoes where ID='" + sectionSalary.ContractID + "'";
                    var lstContractInfoView = DbSqlHelper<VMContractInfo>.SqlQueryCommon(sql);
                    if (lstContractInfoView.Count == 1)
                    {
                        sectionSalaryView.ContractName = lstContractInfoView[0].ContractName;
                    }
                    sectionSalaryView.Year = year;
                    lstSectionSalaryView.Add(sectionSalaryView);
                }

                decimal? totalMoney = 0;
                IQueryable<SectionSalaryDetails> lstSectionSalaryDetails = SectionSalaryDetailsRepository.Entities.Where(s => s.SectionSalaryID == sectionSalary.ID);
                foreach (SectionSalaryDetails sectionSalaryDetails in lstSectionSalaryDetails)
                {
                    if (sectionSalaryDetails.MonthSalary != null)
                    {
                        totalMoney += sectionSalaryDetails.MonthSalary;
                    }
                }

                switch (sectionSalary.Month)
                {
                    case "1":
                        sectionSalaryView.JanuarySalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "2":
                        sectionSalaryView.FebruarySalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "3":
                        sectionSalaryView.MarchSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "4":
                        sectionSalaryView.AprilSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "5":
                        sectionSalaryView.MaySalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "6":
                        sectionSalaryView.JuneSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "7":
                        sectionSalaryView.JulySalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "8":
                        sectionSalaryView.AugustSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "9":
                        sectionSalaryView.SeptemberSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "10":
                        sectionSalaryView.OctoberSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "11":
                        sectionSalaryView.NovemberSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                    case "12":
                        sectionSalaryView.DecemberSalary = totalMoney == 0 ? null : totalMoney;
                        break;
                }
            }
            return lstSectionSalaryView;
        }

        public List<SectionSalaryDetailsView> GetSectionSalaryDetailList(Guid projectID, string contractType, Guid contractID, string year, string month)
        {
            List<SectionSalaryDetailsView> lstSectionSalaryDetailsView = new List<SectionSalaryDetailsView>();
            var queryData = from s in SectionSalaryRepository.Entities
                            join sd in SectionSalaryDetailsRepository.Entities
                            on s.ID equals sd.SectionSalaryID
                            where s.ProjectID == projectID && s.ContractType == contractType && s.ContractID == contractID && s.Year == year && s.Month == month && s.HandleState == "2"
                            select sd;
            foreach (SectionSalaryDetails sectionSalaryDetails in queryData)
            {
                SectionSalaryDetailsView sectionSalaryDetailsView = sectionSalaryDetails.CopyTo<SectionSalaryDetailsView>();
                sectionSalaryDetailsView.IDCAttachment = GetAttachment(sectionSalaryDetails.ID, "WorkerManagement/SectionSalaryList/IDCAttachment");
                sectionSalaryDetailsView.ContractAttachment = GetAttachment(sectionSalaryDetails.ID, "WorkerManagement/SectionSalaryList/ContractAttachment");
                lstSectionSalaryDetailsView.Add(sectionSalaryDetailsView);
            }
            return lstSectionSalaryDetailsView;
        }

        public string GetSectionSalaryID(Guid projectID, string contractType, Guid contractID, string year, string month)
        {
            string sectionSalaryID = string.Empty;
            SectionSalary sectionSalary = SectionSalaryRepository.Entities.SingleOrDefault(s => s.ProjectID == projectID && s.ContractType == contractType && s.ContractID == contractID && s.Year == year && s.Month == month && s.HandleState == "2");
            if (sectionSalary != null)
            {
                sectionSalaryID = sectionSalary.ID.ToString();
            }
            return sectionSalaryID;
        }

        public List<SectionSalaryDetailsView> GetSectionSalaryDetailListForRoster(Guid projectID, string contractType, Guid contractID)
        {
            List<SectionSalaryDetailsView> lstSectionSalaryDetailsView = new List<SectionSalaryDetailsView>();
            var queryData = from s in SectionSalaryRepository.Entities
                            join sd in SectionSalaryDetailsRepository.Entities
                            on s.ID equals sd.SectionSalaryID
                            where s.ProjectID == projectID && s.ContractType == contractType && s.ContractID == contractID && s.HandleState == "2"
                            select sd;
            foreach (SectionSalaryDetails sectionSalaryDetails in queryData)
            {
                SectionSalaryDetailsView sectionSalaryDetailsView = lstSectionSalaryDetailsView.SingleOrDefault(s => s.CertificateNo == sectionSalaryDetails.CertificateNo && s.Name == sectionSalaryDetails.Name);
                if (sectionSalaryDetailsView == null)
                {
                    sectionSalaryDetailsView = new SectionSalaryDetailsView();
                    sectionSalaryDetailsView.CertificateNo = sectionSalaryDetails.CertificateNo;
                    sectionSalaryDetailsView.Name = sectionSalaryDetails.Name;
                    sectionSalaryDetailsView.Sex = sectionSalaryDetails.Sex;
                    sectionSalaryDetailsView.Age = sectionSalaryDetails.Age;
                    sectionSalaryDetailsView.WorkType = sectionSalaryDetails.WorkType;
                    sectionSalaryDetailsView.MonthSalary = sectionSalaryDetails.MonthSalary;
                    lstSectionSalaryDetailsView.Add(sectionSalaryDetailsView);
                }
                else
                {
                    if (sectionSalaryDetails.MonthSalary != null)
                    {
                        decimal? oldMoney = sectionSalaryDetailsView.MonthSalary == null ? 0 : sectionSalaryDetails.MonthSalary;
                        sectionSalaryDetailsView.MonthSalary = oldMoney + sectionSalaryDetails.MonthSalary;
                    }
                }
            }
            return lstSectionSalaryDetailsView.OrderBy(s => s.CertificateNo).ThenBy(s => s.Name).ToList();
        }
        #endregion

        #region 单据加载
        public SectionSalaryView GetSectionSalaryByID(Guid id)
        {
            SectionSalary sectionSalary = SectionSalaryRepository.Entities.SingleOrDefault(t => t.ID == id);
            SectionSalaryView sectionSalaryView = null;
            if (sectionSalary != null)
            {
                sectionSalaryView = new SectionSalaryView();
                sectionSalaryView.ID = sectionSalary.ID;
                sectionSalaryView.FlowCode = sectionSalary.FlowCode;
                sectionSalaryView.ProjectID = sectionSalary.ProjectID;
                sectionSalaryView.ContractType = sectionSalary.ContractType;
                sectionSalaryView.ContractID = sectionSalary.ContractID;
                string sql = "select * from V_ContractInfoes where ID='" + sectionSalary.ContractID + "'";
                var lstContractInfoView = DbSqlHelper<VMContractInfo>.SqlQueryCommon(sql);
                if (lstContractInfoView.Count == 1)
                {
                    sectionSalaryView.ContractName = lstContractInfoView[0].ContractName;
                }
                sectionSalaryView.Year = sectionSalary.Year;
                sectionSalaryView.Month = sectionSalary.Month;
                sectionSalaryView.Attachment = sectionSalary.Attachment;
                sectionSalaryView.RequestDate = sectionSalary.RequestDate;
                sectionSalaryView.RequestPerson = sectionSalary.RequestPerson;
                sectionSalaryView.HandleState = sectionSalary.HandleState;
                sectionSalaryView.AssociatedNodeCode = sectionSalary.AssociatedNodeCode;
                sectionSalaryView.LastUpdateUserDepartment = sectionSalary.LastUpdateUserDepartment;
                sectionSalaryView.LastUpdateUser = sectionSalary.LastUpdateUser;
                sectionSalaryView.LastUpdateTime = sectionSalary.LastUpdateTime;
                sectionSalaryView.SaveState = sectionSalary.SaveState;
            }
            return sectionSalaryView;
        }

        public List<SectionSalaryDetailsView> GetSectionSalaryDetailListForFlow(string sourceType, Guid projectID, string contractType, Guid contractID, Guid sectionSalaryID)
        {
            List<SectionSalaryDetailsView> lstSectionSalaryDetailsView = new List<SectionSalaryDetailsView>();
            if (sourceType == "1")
            {
                var queryData = from s in SectionSalaryRepository.Entities
                                where s.ProjectID == projectID && s.ContractType == contractType && s.ContractID == contractID
                                orderby s.Year, s.Month descending
                                select s;
                SectionSalary sectionSalary = queryData.FirstOrDefault();
                if (sectionSalary != null)
                {
                    sectionSalaryID = sectionSalary.ID;
                }
            }
            IQueryable<SectionSalaryDetails> lstSectionSalaryDetails = SectionSalaryDetailsRepository.Entities.Where(s => s.SectionSalaryID == sectionSalaryID);
            foreach (SectionSalaryDetails sectionSalaryDetails in lstSectionSalaryDetails)
            {
                SectionSalaryDetailsView sectionSalaryDetailsView = sectionSalaryDetails.CopyTo<SectionSalaryDetailsView>();
                if (sourceType == "1")
                {
                    sectionSalaryDetailsView.ID = GuidHelper.NewGuid();
                }
                else
                {
                    sectionSalaryDetailsView.IDCAttachment = GetAttachment(sectionSalaryDetails.ID, "WorkerManagement/SectionSalaryList/IDCAttachment");
                    sectionSalaryDetailsView.ContractAttachment = GetAttachment(sectionSalaryDetails.ID, "WorkerManagement/SectionSalaryList/ContractAttachment"); 
                }
                lstSectionSalaryDetailsView.Add(sectionSalaryDetailsView);
            }
            return lstSectionSalaryDetailsView;
        }
        #endregion

        private string GetAttachment(Guid instanceID, string tag)
        {
            string attachment = string.Empty;
            List<DocumentInfo> documents = DocumentInfoRepository.Entities.Where(d => d.InstanceID == instanceID && d.Tag == tag).ToList();
            for (int i = 0; i < documents.Count(); i++)
            {
                if (i == documents.Count() - 1)
                {
                    attachment += "<a target=\"_blank\" href='" + documents[i].FilePath + "'>" + documents[i].FileName + "</a> ";
                }
                else
                {
                    attachment += "<a target=\"_blank\" href='" + documents[i].FilePath + "'>" + documents[i].FileName + "</a>、 ";
                }
            }
            return attachment;
        }

        #region 单据保存
        public void SaveSectionSalary(SectionSalaryView sectionSalaryView, List<SectionSalaryDetailsView> saveList, bool isUpdateDetails = true)
        {
            SectionSalary record = SectionSalaryRepository.Entities.FirstOrDefault(a => a.ID == sectionSalaryView.ID);
            if (record != null)
            {
                UpdateSectionSalary(record, sectionSalaryView);
            }
            else
            {
                InsertSectionSalary(sectionSalaryView);
            }

            if (isUpdateDetails)
            {
                DeleteSectionSalaryDetails(sectionSalaryView.ID);
                foreach (SectionSalaryDetailsView sectionSalaryDetailsView in saveList)
                {
                    InsertSectionSalaryDetails(sectionSalaryDetailsView);
                }
            }
        }

        private void InsertSectionSalary(SectionSalaryView sectionSalaryView)
        {
            SectionSalary record = new SectionSalary()
            {
                ID = sectionSalaryView.ID,
                FlowCode = sectionSalaryView.FlowCode,
                ProjectID = sectionSalaryView.ProjectID,
                ContractType = sectionSalaryView.ContractType,
                ContractID = sectionSalaryView.ContractID,
                Year = sectionSalaryView.Year,
                Month = sectionSalaryView.Month,
                Attachment = sectionSalaryView.Attachment,
                RequestDate = sectionSalaryView.RequestDate,
                RequestPerson = sectionSalaryView.RequestPerson,
                HandleState = sectionSalaryView.HandleState,
                AssociatedNodeCode = sectionSalaryView.AssociatedNodeCode,
                LastUpdateUserDepartment = sectionSalaryView.LastUpdateUserDepartment,
                LastUpdateUser = sectionSalaryView.LastUpdateUser,
                LastUpdateTime = sectionSalaryView.LastUpdateTime,
                SaveState = sectionSalaryView.SaveState
            };
            SectionSalaryRepository.Insert(record);
        }

        private void UpdateSectionSalary(SectionSalary record, SectionSalaryView sectionSalaryView)
        {
            record.Year = sectionSalaryView.Year;
            record.Month = sectionSalaryView.Month;
            record.Attachment = sectionSalaryView.Attachment;
            record.HandleState = sectionSalaryView.HandleState;
            record.AssociatedNodeCode = sectionSalaryView.AssociatedNodeCode;
            record.LastUpdateUserDepartment = sectionSalaryView.LastUpdateUserDepartment;
            record.LastUpdateUser = sectionSalaryView.LastUpdateUser;
            record.LastUpdateTime = sectionSalaryView.LastUpdateTime;
            record.SaveState = sectionSalaryView.SaveState;
            SectionSalaryRepository.Update(record);
        }

        private void DeleteSectionSalaryDetails(Guid sectionSalaryID)
        {
            List<SectionSalaryDetails> lstSectionSalaryDetails = SectionSalaryDetailsRepository.Entities.Where(a => a.SectionSalaryID == sectionSalaryID).ToList();
            foreach (SectionSalaryDetails sectionSalaryDetails in lstSectionSalaryDetails)
            {
                SectionSalaryDetailsRepository.Delete(sectionSalaryDetails.ID);
            }
        }

        private void InsertSectionSalaryDetails(SectionSalaryDetailsView sectionSalaryDetailsView)
        {
            SectionSalaryDetails record = new SectionSalaryDetails()
            {
                ID = sectionSalaryDetailsView.ID,
                SectionSalaryID = sectionSalaryDetailsView.SectionSalaryID,
                CertificateNo = sectionSalaryDetailsView.CertificateNo,
                Name = sectionSalaryDetailsView.Name,
                Sex = sectionSalaryDetailsView.Sex,
                Age = sectionSalaryDetailsView.Age,
                WorkType = sectionSalaryDetailsView.WorkType,
                MonthSalary = sectionSalaryDetailsView.MonthSalary
            };
            SectionSalaryDetailsRepository.Insert(record);
        }
        #endregion

        public OperationResult Delete(Guid projectID, string contractType, Guid contractID, string year, string month)
        {
            try
            {
                SectionSalary record = SectionSalaryRepository.Entities.SingleOrDefault(t => t.ProjectID == projectID && t.ContractType == contractType && t.ContractID == contractID && t.Year == year && t.Month == month);
                if (record == null)
                    return new OperationResult(OperationResultType.QueryNull, "未找到指定的记录");
                if (record != null)
                {
                    SectionSalaryRepository.Delete(record);
                }

                string sql = @"DELETE FROM SectionSalaryDetails WHERE SectionSalaryID='" + record.ID + "';" +
                              "DELETE FROM BaklogTasks WHERE RecordID='" + record.ID + "';" +
                              "DELETE FROM BaklogTaskTemps WHERE RecordID='" + record.ID + "';" +
                              "DELETE FROM CompleteFlowNodes WHERE RecordID='" + record.ID + "';" +
                              "DELETE FROM FlowGraphNodes WHERE RecordID='" + record.ID + "';" +
                              "DELETE FROM FlowProcessMessages WHERE RecordID='" + record.ID + "';" +
                              "DELETE FROM ProcessedTasks WHERE RecordID='" + record.ID + "';";
                SectionSalaryRepository.ExeSqlCommon(sql);
                return new OperationResult(OperationResultType.Success, "删除成功", record);
            }
            catch (Exception ex)
            {
                return new OperationResult(OperationResultType.Error, "删除失败:" + ex.Message);
            }
        }
    }
}